﻿using FTBS.Models.BLO;
using FTBS.Models.Entities;
using FTBS.Models.Entities.Concert;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace FTBS.Controllers
{
    public class HomeController : Controller
    {
        private TheaterBLO _theaterBlo = new TheaterBLO();
        private HomeBLO _homeBlo = new HomeBLO();
        private ScheduleBLO _scheduleBlo = new ScheduleBLO();
        private FilmBLO _filmBlo = new FilmBLO();
        private CategoryBLO _cateBlo = new CategoryBLO();
        private ShowTimeBLO _showtimeBlo = new ShowTimeBLO();
        private PromotionBLO _promotionBo = new PromotionBLO();
        private CommentBLO _commentBlo = new CommentBLO();
        private UserBLO _userBlo = new UserBLO();
        private TicketBLO _ticketBlo = new TicketBLO();

        public ActionResult Index()
        {
            if (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer")
            {
                return Redirect("/Home/Announcement");
            }
            #region Promotion Film
            //List films have promotion, not max rate
            List<FilmConcertEntity> listFilmPromotion = new List<FilmConcertEntity>();
            listFilmPromotion = _scheduleBlo.GetFilmsPromotion();

            //Film has max rate promotion
            FilmConcertEntity filmBestPromotion = new FilmConcertEntity();
            filmBestPromotion = _scheduleBlo.GetFilmsBestPromtion();

            //List film to show for Film promotion
            List<FilmConcertEntity> list7FilmPromotion = new List<FilmConcertEntity>();
            list7FilmPromotion.Add(filmBestPromotion);

            foreach (var film in listFilmPromotion)
            {
                if (!_homeBlo.IsFilmExistInList(list7FilmPromotion, film))
                {
                    list7FilmPromotion.Add(film);
                }
            }

            #endregion

            #region CommingSoonFilm

            //List film comming soon
            List<FilmConcertEntity> listFilmCommingSoon = new List<FilmConcertEntity>();
            listFilmCommingSoon = _scheduleBlo.GetFilmCommingSoon();

            #endregion

            #region Films are Showimg

            //Load add film are showing to Home Page of Guest
            List<Film> listFilmShowing = new List<Film>();
            listFilmShowing = _scheduleBlo.LoadFilmsAreShowing();

            #endregion

            #region Hot Films
            // Load most lastweek sold films and get top 3 of them
            // DuyHDV
            List<Film> hotFilms = new List<Film>();
            List<Ticket> listTickets = new List<Ticket>();
            listTickets = _scheduleBlo.GetListTicket();
            List<Film> showingFilms = _scheduleBlo.GetListOfFilmShowing();
            Dictionary<int, int> listFilmCount = new Dictionary<int, int>();
            foreach (var film in showingFilms)
            {
                int countTicket = 0;
                foreach (var ticket in listTickets)
                {
                    if (film.FilmId == ticket.Schedule.FilmId)
                    {
                        countTicket = countTicket + 1;
                    }
                }
                if (countTicket > 0)
                {
                    listFilmCount.Add(film.FilmId, countTicket);
                }
            }
            var listSortedFilms = (from item in listFilmCount
                                   orderby item.Value descending
                                   select item);//.Take(3);
            List<Film> listHotFilms = new List<Film>();
            foreach (var item in listSortedFilms)
            {
                foreach (var film in showingFilms)
                {
                    if (item.Key == film.FilmId)
                    {
                        listHotFilms.Add(film);
                    }
                }
            }
            #endregion

            #region Fast Buy
            // List Theaters
            List<SelectListItem> theaters = new List<SelectListItem>();
            foreach (var item in _theaterBlo.GetAllTheaterInfo())
            {
                SelectListItem theater = new SelectListItem();
                theater.Text = item.TheaterName;
                theater.Value = item.TheaterId.ToString();
                theaters.Add(theater);
            }  
            SelectList listTheaters = new SelectList(theaters, "Value", "Text");
            ViewBag.ListTheaters = listTheaters;

            // List Dates
            List<SelectListItem> dItems = new List<SelectListItem>();
            SelectListItem fistItem = new SelectListItem();
                fistItem.Text = "--- Chọn ngày ---";
                fistItem.Value = "0";
                dItems.Add(fistItem);
            SelectList listDates = new SelectList(dItems,"Value","Text");
            ViewBag.ListDates = listDates;

            // List Film
            List<SelectListItem> films = new List<SelectListItem>();
            foreach (var item in _filmBlo.GetAllShowingFilms())
            {
                SelectListItem film = new SelectListItem();
                film.Text = item.Name;
                film.Value = item.FilmId.ToString();
                films.Add(film);
            }
            SelectList listFilms = new SelectList(films, "Value", "Text");
            ViewBag.ListFilms = listFilms;

            // List ShowTimes
            List<SelectListItem> sItems = new List<SelectListItem>();
            SelectListItem fistSItem = new SelectListItem();
            fistSItem.Text = "--- Chọn giờ ---";
            fistSItem.Value = "0";
            sItems.Add(fistSItem);
            SelectList listShowtimes = new SelectList(sItems, "Value", "Text");
            ViewBag.ListShowTimes = listShowtimes;


            #endregion

            ViewBag.ListFilmPromotion = list7FilmPromotion;
            ViewBag.ListFilmCommingSoon = listFilmCommingSoon;
            ViewBag.ListFilmShowing = listFilmShowing;  
            ViewBag.ListHotFilms = listHotFilms;

            return View();
        }


        /// <summary>
        /// Home page for Customer
        /// </summary>
        /// <returns></returns>
        /// <author>VuongVT</author>
        public ActionResult Customer()
        {
            if (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer")
            {
                return Redirect("/Home/Announcement");
            }
            //List films have promotion, not max rate
            List<FilmConcertEntity> listFilmPromotion = new List<FilmConcertEntity>();
            listFilmPromotion = _scheduleBlo.GetFilmsPromotion();

            //Film has max rate promotion
            FilmConcertEntity filmBestPromotion = new FilmConcertEntity();
            filmBestPromotion = _scheduleBlo.GetFilmsBestPromtion();

            //List film to show for Film promotion
            List<FilmConcertEntity> list7FilmPromotion = new List<FilmConcertEntity>();
            list7FilmPromotion.Add(filmBestPromotion);

            foreach (var film in listFilmPromotion)
            {
                if (!_homeBlo.IsFilmExistInList(list7FilmPromotion, film))
                {
                    list7FilmPromotion.Add(film);
                }
            }

            //List film comming soon
            List<FilmConcertEntity> listFilmCommingSoon = new List<FilmConcertEntity>();
            listFilmCommingSoon = _scheduleBlo.GetFilmCommingSoon();

            // Load most lastweek sold films and get top 7 of them
            // DuyHDV
            #region List of film has been showed most

            List<Film> hotFilms = new List<Film>();
            List<Ticket> listTickets = new List<Ticket>();
            listTickets = _scheduleBlo.GetListTicket();
            List<Film> showingFilms = _scheduleBlo.GetListOfFilmShowing();
            Dictionary<int, int> listFilmCount = new Dictionary<int, int>();
            foreach (var film in showingFilms)
            {
                int countTicket = 0;
                foreach (var ticket in listTickets)
                {
                    if (film.FilmId == ticket.Schedule.FilmId)
                    {
                        countTicket = countTicket + 1;
                    }
                }
                if (countTicket > 0)
                {
                    listFilmCount.Add(film.FilmId, countTicket);
                }
            }
            var listSortedFilms = (from item in listFilmCount
                                   orderby item.Value descending
                                   select item).Take(9);

            foreach (var item in listSortedFilms)
            {
                foreach (var film in showingFilms)
                {
                    if (item.Key == film.FilmId)
                    {
                        if (hotFilms.Count < 7)
                        {
                            hotFilms.Add(film);
                        }
                    }
                }
            }

            #endregion

            //Load add film are showing to Home Page of Customer
            List<Film> listFilmShowing = new List<Film>();
            listFilmShowing = _scheduleBlo.LoadFilmsAreShowing();


            ViewBag.ListFilmPromotion = list7FilmPromotion;
            ViewBag.ListFilmCommingSoon = listFilmCommingSoon;
            //ViewBag.ListMostShowingFilms = hotFilms;
            ViewBag.ListFilmShowing = listFilmShowing;
            return View(hotFilms);
        }

        /// <summary>
        /// Partial view for List of Theater nearest
        /// </summary>
        /// <param name="latitude">latitude of user</param>
        /// <param name="longitude">longitude of user</param>
        /// <returns>PartialView: NearestTheater</returns>
        public PartialViewResult NearestTheater(string latitude, string longitude)
        {
            List<TheaterConcertEntity> listTheater = new List<TheaterConcertEntity>();
            double customerLatitude = Convert.ToDouble(latitude);
            double customerLongitude = Convert.ToDouble(longitude);
            listTheater = _homeBlo.GetListNearestTheater(latitude, longitude);
            ViewBag.Latitude = latitude;
            ViewBag.Longitude = longitude;
            return PartialView("NearestTheater", listTheater);
        }

        /// <summary>
        /// Partial view for List of Theater nearest
        /// </summary>
        /// <param name="latitude">latitude of user</param>
        /// <param name="longitude">longitude of user</param>
        /// <returns>PartialView: NearestTheater</returns>
        public PartialViewResult NearestTheaterExisted(string latitude, string longitude, string listPositionExist, string listNearestTheaterExisted)
        {
            List<TheaterConcertEntity> listTheater = new List<TheaterConcertEntity>();
            List<string> position = _homeBlo.GetLatitudeAndLongitude(listPositionExist);
            double oldLatitude = Convert.ToDouble(position[0].Trim());
            double oldLongitude = Convert.ToDouble(position[1].Trim());
            double customerLatitude = Convert.ToDouble(latitude);
            double customerLongitude = Convert.ToDouble(longitude);
            if (customerLatitude != oldLatitude || customerLongitude != oldLongitude)
            {
                if (!_homeBlo.IsAroundOneKm(oldLatitude, oldLongitude, customerLatitude, customerLongitude))
                {
                    listTheater = _homeBlo.GetListNearestTheater(latitude, longitude);
                    ViewBag.Latitude = latitude;
                    ViewBag.Longitude = longitude;
                }
                else
                {
                    ViewBag.Latitude = position[0];
                    ViewBag.Longitude = position[1];
                    listTheater = _homeBlo.GetListTheaterPosition(listNearestTheaterExisted);
                }
            }
            else
            {
                ViewBag.Latitude = position[0];
                ViewBag.Longitude = position[1];
                listTheater = _homeBlo.GetListTheaterPosition(listNearestTheaterExisted);
            }
            return PartialView("NearestTheater", listTheater);
        }

        /// <summary>
        /// Show list film suggestion for Guest
        /// </summary>
        /// <param name="listCategoryView">localStorage value</param>
        /// <returns>PartialView FilmsSuggestion</returns>
        /// <author>VuongVT</author>
        [HttpGet]
        public PartialViewResult GetListFilmSuggestionGuest(string listCategoryView)
        {
            List<Film> listFilmSuggest = new List<Film>();
            List<LocalStorageConcertEntity> listViewResult = _homeBlo.GetListViewResultCategory(listCategoryView);
            listFilmSuggest = _homeBlo.GetListFilmSuggestionForGuest(listViewResult);
            return PartialView("FilmsSuggestion", listFilmSuggest);
        }

        /// <summary>
        /// Show list film suggestion for Customer
        /// </summary>
        /// <param name="listCategoryView">localStorage value</param>
        /// <returns>PartialView FilmsSuggestion</returns>
        /// <author>VuongVT</author>
        [HttpGet]
        public PartialViewResult GetListFilmSuggestionCustomer(string listCategoryView)
        {
            List<Film> listFilmSuggestCustomer = new List<Film>();
            string userName = this.Session["UserName"] as string;
            if (userName != null)
            {
                List<LocalStorageConcertEntity> listViewResult = _homeBlo.GetListViewResultCategory(listCategoryView);
                listFilmSuggestCustomer = _homeBlo.GetListFilmSuggestionForCustomer(listViewResult, userName);
            }
            return PartialView("FilmsSuggestion", listFilmSuggestCustomer);
        }


        public ActionResult Detail(int id)
        {
            if (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer")
            {
                return Redirect("/Home/Announcement");
            }
            Film film = new Film();
            film = _filmBlo.LoadFilmsById(id);
            //ViewBag.DeadLineForBooking = _theaterBlo.GetTheaterById(scheduleResult.TheaterId).DeadlineForBooking;
            ViewBag.Schedule = _scheduleBlo.GetListScheduleById(id);
            ViewBag.Comments = _commentBlo.LoadCommentByFilm(id);
            ViewBag.SameCate = _scheduleBlo.GetFilmSameCategory(film.CategoryId, id);
            return View(film);
        }

        public ActionResult WriteComment(int filmId, string username, string content)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer"))
            {
                return Redirect("/Home/Announcement");
            }
            Comment comment = new Comment();
            comment.FilmId = filmId;
            comment.UserName = username;
            comment.CommentContent = content;
            comment.Status = true;
            comment.IsDeleted = false;
            var result = _commentBlo.WriteComment(comment);
            if (result)
            {
                return PartialView("_Comment", _commentBlo.LoadCommentByFilm(filmId));
            }
            return RedirectToAction("Detail/" + filmId);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        /// <author>DUYHDV</author>
        /// <date>2014/03/29</date>
        public ActionResult Announcement()
        {
            this.Session["RoleName"] = null;
            this.Session["Account"] = null;
            this.Session["Number"] = null;
            this.Session["Email"] = null;
            this.Session["UserName"] = null;
            return View();
        }

        /// <summary>
        /// Create promotion home page
        /// </summary>
        /// <returns></returns>
        public ActionResult Promotion()
        {
            if (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer")
            {
                return Redirect("/Home/Announcement");
            }
            List<Schedule> listScheduleShowing = _scheduleBlo.GetSchedulesPro();
            //List<Schedule> listPromotionSchedule =( from s in listScheduleShowing where s.PromotionId!= null orderby s.PromotionId select s).ToList();
            ViewBag.ListSchedule = listScheduleShowing;
            var listPromotions = _scheduleBlo.GetCurrentPromotion();
            return View(listPromotions);
        }

        /// <summary>
        /// Create a page show all theaters in the system
        /// </summary>
        /// <returns></returns>
        public ActionResult Theaters()
        {
            if (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer")
            {
                return Redirect("/Home/Announcement");
            }
            List<Theater> listTheater = new List<Theater>();
            var results = from theater in _theaterBlo.GetAllTheaterInfo()
                          orderby theater.UserName
                          select theater;
            listTheater = results.ToList();
            return View(listTheater);
        }

        /// <summary>
        /// Create a page show all suppliers
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public ActionResult TheatersGroups()
        {
            if (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer")
            {
                return Redirect("/Home/Announcement");
            }
            List<User> listSupplier = new List<User>();
            var suppliers = _userBlo.DisplayAllSuppliers();
            listSupplier = (
                from sup in suppliers
                where sup.IsActive == true
                select sup
                ).ToList();
            return View(listSupplier);
        }

        /// <summary>
        /// Create a page show all theater of a supplier
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public ActionResult Group(string group)
        {
            if (this.Session["RoleName"] != null && this.Session["UserName"] != null && this.Session["Account"] != null && this.Session["RoleName"].ToString().Trim() != "Customer")
            {
                return Redirect("/Home/Announcement");
            }
            List<Theater> listTheaters = new List<Theater>();
            listTheaters = _theaterBlo.GetTheatersBySupplier(group);
            ViewBag.supplier = group;
            return View(listTheaters);
        }

        #region Get films, theaters, and their schedules for user selections - DuyHDV
        /// <summary>
        /// Get Theaters in two condition: have filmId or do not have filmId
        /// </summary>
        /// <param name="filmId"></param>
        /// <returns>list of theaters</returns>
        public JsonResult GetTheatesrByFilm(int filmId)
        {
            List<SelectListItem> theaters = new List<SelectListItem>();
            if (filmId != 0)
            {
                foreach (var item in _scheduleBlo.GetListTheaterWhenChooseFilm(filmId))
                {
                    SelectListItem theater = new SelectListItem();
                    theater.Text = item.TheaterName;
                    theater.Value = item.TheaterId.ToString();
                    theaters.Add(theater);
                }
            }
            else
            {
                foreach (var item in _theaterBlo.GetAllTheaterInfo())
                {
                    SelectListItem theater = new SelectListItem();
                    theater.Text = item.TheaterName;
                    theater.Value = item.TheaterId.ToString();
                    theaters.Add(theater);
                }
            }
            SelectList listTheaters = new SelectList(theaters, "Value", "Text");
            return Json(listTheaters, JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// 
        /// Get Films in two condition: have theaterId or do not have theaterID
        /// </summary>
        /// <param name="theaterId"></param>
        /// <returns></returns>
        public JsonResult GetFilmsByTheater(int theaterId)
        {
            List<SelectListItem> films = new List<SelectListItem>();
            if (theaterId != 0)
            {
                foreach (var item in _scheduleBlo.GetListFilmWhenChooseTheater(theaterId))
                {
                    SelectListItem film = new SelectListItem();
                    film.Text = item.Name;
                    film.Value = item.FilmId.ToString();
                    films.Add(film);
                }
            }
            else
            {
                foreach (var item in _filmBlo.GetAllShowingFilms())
                {
                    SelectListItem film = new SelectListItem();
                    film.Text = item.Name;
                    film.Value = item.FilmId.ToString();
                    films.Add(film);
                }
            }
            SelectList listFilms = new SelectList(films, "Value", "Text");
            return Json(listFilms, JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="theaterId"></param>
        /// <param name="FilmId"></param>
        /// <returns></returns>
        public JsonResult GetDates(int theaterId, int filmId)
        {
            List<SelectListItem> dates = new List<SelectListItem>();
            if (theaterId != 0 && filmId != 0)
            {
                foreach (var item in _scheduleBlo.GetListShowTimeWhenChooseTheater(theaterId, filmId))
                {
                    SelectListItem date = new SelectListItem();
                    date.Text = item.DateOfSchedule.ToString("dd/MM/yyyy");
                    date.Value = item.DateOfSchedule.ToString("dd/MM/yyyy");
                    dates.Add(date);
                }
            }
            SelectList listDates = new SelectList(dates, "Value", "Text");
            return Json(listDates, JsonRequestBehavior.AllowGet);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="theaterId"></param>
        /// <param name="FilmId"></param>
        /// <returns></returns>
        public JsonResult GetShowtimes(int theaterId, int filmId, string date)
        {
            var arrayDate = date.Split('/');
            DateTime dateValue = new DateTime(int.Parse(arrayDate[2]), int.Parse(arrayDate[1]), int.Parse(arrayDate[0]));

            List<SelectListItem> showtimes = new List<SelectListItem>();
            foreach (var item in _scheduleBlo.GetListShowTimeForFastBuy(theaterId, filmId, dateValue))
            {
                SelectListItem showtime = new SelectListItem();
                showtime.Text = item.Time.ToString("hh:mm");
                showtime.Value = item.ShowTimeId.ToString();
                showtimes.Add(showtime);
            }
            SelectList listShowtimes = new SelectList(showtimes, "Value", "Text");
            return Json(listShowtimes, JsonRequestBehavior.AllowGet);
        }
        #endregion
    }
}
